home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / system / np100.zip / NP.ASM < prev    next >
Assembly Source File  |  1988-11-30  |  7KB  |  362 lines

  1. ;History:38,1
  2.  
  3. comment !
  4.  * Copyright 1988 By Russell Nelson.  Don't try to make money off of it, and
  5.  * don't pretend that you wrote it.
  6.  *
  7.  * Compu$erve: 70441,205
  8.  * GEnie: BH01
  9.  * Internet: nelson@clutx.clarkson.edu
  10.  * BITNET: NELSON@CLUTX
  11.  * Fido/Opus:  Russ Nelson@1:260/360
  12. !
  13.  
  14. code    segment    public
  15.     assume    cs:code, ds:code
  16.  
  17.     org    2ch
  18. phd_environ    dw    ?
  19.  
  20.     org    5ch
  21. phd_fcb1    label    byte
  22.  
  23.     org    100h
  24. start:
  25.     jmp    start_1
  26.  
  27. went_tsr    db    ?        ;non-zero if a previous cmd went TSR.
  28. first_one    dw    0        ;segment of line buffer.
  29. highest_phd    dw    ?        ;address of highest phd we've seen.
  30. not_yet_flag    db    ?        ;='.' if we should print this one.
  31. done_one    db    ?        ;non-zero if we've printed a program
  32.                     ;  name and hence should skip command.com
  33. command        db    'COMMAND.'    ;name of command.com
  34.  
  35.     assume    ds:nothing
  36.  
  37.  
  38. compare_command:
  39.     mov    di,offset command    ;point to command.com.
  40. compare:
  41. ;enter with ds:bp -> name to test, cs:di -> name to test it against.
  42. ;exit with zr if they're equal, nz if not equal.
  43.     mov    si,bp
  44. compare_0:
  45.     lodsb                ;compare two characters.
  46.     call    tolower
  47.     cmp    cs:[di],al
  48.     jne    compare_1        ;give up if they're different.
  49.     cmp    al,'.'            ;success when we hit the extension.
  50.     je    compare_1
  51.     inc    di
  52.     jmp    compare_0
  53. compare_1:
  54.     ret
  55.  
  56.  
  57. tolower:
  58.     cmp    al,'a'            ;Uppercase letter.
  59.     jb    tolower_2
  60.     cmp    al,'z'
  61.     ja    tolower_2
  62.     sub    al,20h
  63. tolower_2:
  64.     ret
  65.  
  66. print_name:
  67. ;enter with ds:si -> name of a loaded program.
  68.  
  69. ;
  70. ;find where the pathname ends and the filename begins.
  71. ;
  72. print_name_3:
  73.     mov    bp,si            ;remember where we should print from.
  74. print_name_1:
  75.     lodsb
  76.     cmp    al,'\'            ;restart if we hit either path separator.
  77.     je    print_name_3
  78.     cmp    al,'/'
  79.     je    print_name_3
  80.     or    al,al            ;continue until we hit the end of the string.
  81.     jne    print_name_1
  82.  
  83. ;
  84. ; Should we store because of a TSR?
  85. ;
  86.     cmp    went_tsr,0        ;should we use this as the last TSR?
  87.     jne    print_tsr        ;not yet - go test to see if we should.
  88. ;
  89. ; Have we reached the last TSR yet?
  90. ;
  91.     cmp    not_yet_flag,'.'    ;should we print yet?
  92.     jne    print_test        ;not yet - go test to see if we should.
  93. ;
  94. ; Did we just print a program?  If so, we can skip the [COMMAND] that follows
  95. ; it.  Otherwise, we should print [COMMAND].
  96. ;
  97.     xor    al,al            ;get and reset done_one
  98.     xchg    al,done_one
  99.     or    al,al            ;did we just do a program?
  100.     je    print_name_6        ;no - we can print [COMMAND] here.
  101. ;
  102. ; Avoid printing [COMMAND] immediately after a program that spawned command.com.
  103. ;
  104.     call    compare_command        ;compare command.com to the current one.
  105.     je    print_name_2        ;go if they're equal.
  106.  
  107. print_name_6:
  108.  
  109. ;
  110. ;print their name.
  111. ;
  112.     mov    si,bp            ;now restart after the rightmost slash.
  113.     mov    dl,'['
  114.     mov    ah,2
  115.     int    21h
  116. print_name_4:
  117.     lodsb
  118.     or    al,al            ;give up when we hit the end.
  119.     je    print_name_5
  120.     cmp    al,'.'            ;give up when we hit the extension.
  121.     je    print_name_5
  122.     mov    dl,al
  123.     mov    ah,2
  124.     int    21h
  125.     jmp    print_name_4
  126. print_name_5:
  127.     mov    dl,']'
  128.     mov    ah,2
  129.     int    21h
  130. ;
  131. ; If we just printed a program, remember it in done_one.
  132. ;
  133.     call    compare_command        ;compare it to the current one.
  134.     je    print_name_2        ;go if they're equal.
  135.  
  136.     inc    done_one        ;say that we just did a program.
  137.  
  138. print_name_2:
  139.     ret
  140.  
  141. print_test:
  142. ;
  143. ; See if we have reached the last TSR yet.
  144. ;
  145.     mov    di,offset phd_fcb1+1    ;point to their filename.
  146.     call    compare
  147.     jne    print_test_1        ;go if they're different.
  148.  
  149.     mov    not_yet_flag,'.'    ;print the next one.
  150. print_test_1:
  151.     ret
  152.  
  153.  
  154. print_tsr:
  155.     mov    di,offset phd_fcb1+1    ;point to their filename.
  156.     mov    si,bp
  157. print_tsr_0:
  158.     lodsb                ;print_tsr_ two characters.
  159.     call    tolower
  160.     mov    cs:[di],al
  161.     inc    di
  162.     cmp    al,'.'            ;success when we hit the extension.
  163.     jne    print_tsr_0
  164.     ret
  165.  
  166.  
  167. prompt:
  168.     assume    ds:code
  169.  
  170.     cmp    first_one,0        ;do we have a segment yet?
  171.     jne    prompt_0        ;yes.
  172.     mov    first_one,dx
  173. prompt_0:
  174.     cmp    first_one,dx        ;is this command.com?
  175.     jne    prompt_3        ;no - don't print anything.
  176.  
  177.     mov    al,phd_fcb1+1        ;if al = '.', then the filename is null.
  178.     mov    not_yet_flag,al        ;if not_yet_flag = '.', print the name.
  179.     mov    done_one,0        ;say that we haven't done any yet.
  180.  
  181. ;
  182. ; Get the first memory block into ES (undocumented).
  183. ;
  184.     mov    ah,52h
  185.     int    21h
  186.     mov    es,es:[bx-2]
  187.  
  188. ;
  189. ; Now we step through the phd's (program headers)
  190. ;
  191.     mov    highest_phd,0        ;remember the highest phd we've seen.
  192. prompt_2:
  193.     cmp    byte ptr es:[0],'M'    ;All but the last block start with 'M'.
  194.     jne    prompt_3
  195.  
  196. ;
  197. ; Keep track of the highest phd we've seen, so we don't repeat any.
  198. ;
  199.     mov    ax,es:[1]        ;get the phd (owner).
  200.     cmp    ax,highest_phd        ;is this one higher?
  201.     jbe    prompt_4        ;no - skip it.
  202.     mov    highest_phd,ax        ;yes - remember it.
  203. ;
  204. ; Now that we've found the next phd, get its environment.  However, we have to
  205. ; be careful, because some TSRs free their environment memory block in an effort
  206. ; to conserve memory.  This is good and bad, because freeing their environment
  207. ; makes it impossible for us to determine the program name.
  208. ;
  209.     push    ds
  210.     mov    ds,ax            ;point to the phd.
  211.     mov    bx,phd_environ        ;get the environment.
  212.     dec    bx
  213.     mov    ds,bx            ;point to its header.
  214.     cmp    ds:[1],ax        ;do we still own this memory block?
  215.     jne    prompt_8        ;no - forget it.
  216.  
  217. ;
  218. ; Now skip to the end of the environment where the program name is kept.
  219. ;
  220.     mov    si,16-1            ;look for the end of all the strings.
  221. prompt_5:
  222.     inc    si
  223.     cmp    word ptr [si],0        ;did we hit the end yet?
  224.     jne    prompt_5
  225.  
  226.     add    si,4            ;point to the name of the program.
  227.     call    print_name
  228. prompt_8:
  229.     pop    ds
  230. ;
  231. ; Skip to the next memory block.
  232. ;
  233. prompt_4:
  234.     mov    ax,es            ;add the size of this memory block
  235.     add    ax,es:[3]        ;  to get to the next segment.
  236.     inc    ax
  237.     mov    es,ax
  238.     jmp    prompt_2
  239. prompt_3:
  240.     mov    went_tsr,0        ;Okay, we're done with TSRs.
  241.     ret
  242.  
  243.     assume    ds:nothing
  244.  
  245. their_27 dd    ?            ;remember what their interrupt 27 was.
  246.  
  247. our_27:
  248.     pushf                ;save the flags just in case.
  249.     inc    went_tsr
  250.     popf
  251.     jmp    their_27
  252.  
  253.  
  254. their_21 dd    ?            ;remember what their interrupt 21 was.
  255.  
  256. our_21:
  257. ;
  258. ; Check for buffered input, and save everything if we've got one.
  259. ;
  260.     pushf
  261.     cmp    ah,31h            ;TSR call?
  262.     jne    our_21_2
  263.     inc    went_tsr        ;yes - remember it.
  264. our_21_2:
  265.     cmp    ah,0ah            ;buffered input?
  266.     jnz    our_21_1
  267.  
  268.     push    ax
  269.     push    bx            ;save regs
  270.     push    cx
  271.     push    dx
  272.     push    si
  273.     push    di
  274.     push    bp
  275.     push    ds
  276.     push    es
  277.  
  278.     mov    dx,ds            ;remember their buffer's segment in dx.
  279.  
  280.     mov    ax,cs            ;set up ds
  281.     mov    ds,ax
  282.  
  283.     call    prompt
  284.  
  285.     pop    es
  286.     pop    ds
  287.     pop    bp
  288.     pop    di
  289.     pop    si
  290.     pop    dx
  291.     pop    cx
  292.     pop    bx
  293.     pop    ax
  294.  
  295. our_21_1:
  296.     popf
  297.     jmp    cs:their_21
  298.  
  299.  
  300. start_1:
  301. ;
  302. ; Check for MS-LOSS 3.x
  303. ;
  304.     mov    ah,30h
  305.     int    21h
  306.     cmp    al,3
  307.     jae    start_3
  308.     mov    dx,offset bad_ver_msg
  309.     mov    ah,9
  310.     int    21h
  311.     int    20h
  312. start_3:
  313.  
  314. ;
  315. ; Terminate the filename in phd_fcb1 with '.' instead of ' '.
  316. ;
  317.     mov    si,offset phd_fcb1+1    ;point to their filename.
  318. start_2:
  319.     lodsb
  320.     cmp    al,' '
  321.     jne    start_2
  322.     mov    byte ptr ds:[si-1],'.'    ;put a period after the filename.
  323.  
  324. ;
  325. ; Intercept interrupt 21.
  326. ;
  327.     mov    ax,3521h
  328.     int    21h
  329.     mov    word ptr their_21,bx
  330.     mov    word ptr their_21+2,es
  331.  
  332.     mov    dx,offset our_21
  333.     mov    ax,2521h
  334.     int    21h
  335. ;
  336. ; Intercept interrupt 27.
  337. ;
  338.     mov    ax,3527h
  339.     int    21h
  340.     mov    word ptr their_27,bx
  341.     mov    word ptr their_27+2,es
  342.  
  343.     mov    dx,offset our_27
  344.     mov    ax,2527h
  345.     int    21h
  346. ;
  347. ; and TSR.
  348. ;
  349.     mov    dx,offset start_1+15
  350.     shr    dx,1
  351.     shr    dx,1
  352.     shr    dx,1
  353.     shr    dx,1
  354.     mov    ah,31h
  355.     int    21h
  356.  
  357. bad_ver_msg    db    "Requires MS-LOSS 3.x or greater$"
  358.  
  359. code    ends
  360.  
  361.     end    start
  362.